#include <func.h>
#include "Task.h"
#include "Crypto.h"

void upload_chunk(void* arg, Thread* thread)
{
    // 1. 解析参数
    Param* param = (Param*) arg;
    // 文件大小 sha256sum  路径
    int epfd = param->epfd;
    int connfd = param->connfd;
    int sequence = atoi(strtok(param->req.value, SPACES));
    long fsize = atol(strtok(NULL, SPACES));
    const char* sha256sum = strtok(NULL, SPACES);
    const char* path = strtok(NULL, SPACES);
    const char* token = strtok(NULL, SPACES);
    printf("DEBUG: %d %ld %s %s %s\n", sequence, fsize, sha256sum, path, token);

    // 2. 校验 token
    Response resp;
    bzero(&resp, sizeof(resp));

    int user_id;
    char username[26];
    if (verify_jwt(token, &user_id, username) == false) {
        resp.status = RESP_NOT_AUTH;
        resp.length = 0;
        int length = 2 * sizeof(int);
        send(connfd, &length, sizeof(int), MSG_WAITALL);
        send(connfd, &resp, length, MSG_WAITALL);
        return ;
    }
    printf("DEBUG: user_id = %d, username = %s\n", user_id, username);

    // 3. 判断路径是否存在
    MYSQL* mysql = thread->mysql;
    int path_id = path_exist(mysql, path);
    if (path_id == 0) {
        path_create(mysql, user_id, path, 'f');
        path_id = path_exist(mysql, path);
    }
    
    // 4. 判断文件是否已存在
    if (file_exist(mysql, sha256sum)) {
        // 文件已存在，不需要再传
        printf("DEBUG: file exists\n");
        resp.status = RESP_EXIST;
        resp.length = 0;

        int length = 2 * sizeof(int);
        send(connfd, &length, sizeof(int), MSG_WAITALL);
        send(connfd, &resp, length, MSG_WAITALL);
        return ;
    }
    // 5. 文件不存在
    resp.status = RESP_NOEXIST;
    resp.length = 0;
    int length = 2 * sizeof(int);
    send(connfd, &length, sizeof(int), MSG_WAITALL);
    send(connfd, &resp, length, MSG_WAITALL);

    // 接收文件
    char file_path[PATH_MAX];
    sprintf(file_path, "upload/%s", sha256sum);
    int fd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    char buf[4096];
    long nbytes = 0;
    while (nbytes < fsize) {
        int length = fsize - nbytes >= 4096 ? 4096 : fsize - nbytes;
        int n = recv(connfd, buf, length, MSG_WAITALL);
        if (n == -1) {
            // 发生错误
            fprintf(stderr, "recv(): %s\n", strerror(errno));
        } else if (n == 0) {
            // 对端断开连接
        } else {
            write(fd, buf, n);
            nbytes += n;
        }
    }
    
    file_create(mysql, sha256sum, fsize);
    int file_id = file_exist(mysql, sha256sum);
    pathtofile_create(mysql, path_id, file_id, sequence);

    epoll_add(epfd, connfd);
    free(arg);
    close(fd);
}
